package org.firefly.component;

import org.firefly.entity.TimeCapsule;
import org.firefly.repository.TimeCapsuleRepository;
import org.firefly.service.TimeCapsuleService;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

@Component
public class QuartzJobRecovery {

    private static final Logger log = LoggerFactory.getLogger(QuartzJobRecovery.class);

    private final TimeCapsuleRepository capsuleRepository;
    private final TimeCapsuleService capsuleService;
    private final Scheduler scheduler;

    @Autowired
    public QuartzJobRecovery(TimeCapsuleRepository capsuleRepository,
                             TimeCapsuleService capsuleService,
                             Scheduler scheduler) {
        this.capsuleRepository = capsuleRepository;
        this.capsuleService = capsuleService;
        this.scheduler = scheduler;
    }

    /**
     * 应用启动后恢复所有未触发的任务
     */
    @EventListener(ApplicationReadyEvent.class)
    public void recoverJobsAfterStartup() {
        log.info("Starting job recovery process...");

        // 获取所有未开启且开启时间在未来或位置触发的胶囊
        List<TimeCapsule> pendingCapsules = capsuleRepository.findByOpenedFalse();

        int recoveredCount = 0;
        int skippedCount = 0;

        for (TimeCapsule capsule : pendingCapsules) {
            try {
                // 检查任务是否已经存在
                JobKey jobKey = new JobKey("capsule_" + capsule.getId());

                if (!scheduler.checkExists(jobKey)) {
                    if (shouldRecoverCapsule(capsule)) {
                        log.info("Recovering job for capsule ID: {}", capsule.getId());
                        capsuleService.scheduleCapsuleOpening(capsule);
                        recoveredCount++;
                    } else {
                        skippedCount++;
                    }
                }
            } catch (SchedulerException e) {
                log.error("Error checking job existence for capsule ID: " + capsule.getId(), e);
            } catch (Exception e) {
                log.error("Failed to recover job for capsule ID: " + capsule.getId(), e);
            }
        }

        log.info("Job recovery completed. Recovered: {}, Skipped: {}, Total: {}",
                recoveredCount, skippedCount, pendingCapsules.size());
    }

    /**
     * 判断胶囊是否需要恢复
     */
    private boolean shouldRecoverCapsule(TimeCapsule capsule) {
        // 如果是时间触发胶囊且开启时间已过，则不恢复
        if (capsule.getOpenDate() != null && capsule.getOpenDate().isBefore(LocalDateTime.now())) {
            log.warn("Skipping expired capsule ID: {}", capsule.getId());
            return false;
        }

        // 如果是位置胶囊且没有位置信息
        if (capsule.getType() == TimeCapsule.CapsuleType.LOCATION &&
                (capsule.getLatitude() == null || capsule.getLongitude() == null)) {
            log.warn("Skipping location capsule without coordinates ID: {}", capsule.getId());
            return false;
        }

        return true;
    }

    /**
     * 手动触发任务恢复
     */
    public void manuallyTriggerRecovery() {
        log.info("Manually triggering job recovery...");
        recoverJobsAfterStartup();
    }
}